package com.xbongbong.crm.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.feign.ChartFeignClient;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.pojo.IdNamePojo;
import com.xbongbong.paas.pojo.IdNamePropertyPojo;
import com.xbongbong.paas.pojo.StageFindPojo;
import com.xbongbong.paas.pojo.UserSimpPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.DynamicManagerLevelEnum;
import com.xbongbong.pro.enums.ReportTypeEnum;
import com.xbongbong.pro.enums.StatisticOptionEnum;
import com.xbongbong.pro.enums.TimeTypeEnum;
import com.xbongbong.pro.enums.WorkReportEnum;
import com.xbongbong.pro.enums.errorcodes.WorkReportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.service.stage.StageFindStrategy;
import com.xbongbong.pro.service.stage.factory.StageFindFactory;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartDtoHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartQueryHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.ThroughHelp;
import com.xbongbong.pro.service.toolbox.statistic.util.ChartResultUtil;
import com.xbongbong.pro.statistic.enums.NumFormatEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.enums.ThroughSourcePageEnum;
import com.xbongbong.pro.statistic.enums.ValueTypeEnum;
import com.xbongbong.pro.statistic.pojo.TimePojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPojo;
import com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo;
import com.xbongbong.pro.statistic.through.pojo.dto.ThroughDTO;
import com.xbongbong.pro.webdetail.pojo.WorkReportDetailStatisicPojo;
import com.xbongbong.pro.webdetail.pojo.WorkReportDetailStatisticResultPojo;
import com.xbongbong.pro.workreport.pojo.vo.WorkReportDetailStatisticsVO;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkPlanEntity;
import com.xbongbong.saas.domain.entity.WorkReportSetEntity;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.enums.business.WorkReportPlanEnum;
import com.xbongbong.saas.enums.business.WorkReportTypeEnum;
import com.xbongbong.saas.model.WorkReportModel;
import com.xbongbong.saas.model.WorkReportSetModel;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author sunshaoxiang
 * @ClassName workReportHelp
 * @Description 工作报告help
 * @Date 2022/6/9 10:02
 * @Version 1.0
 **/
@Component
public class WorkReportHelp {

    public static final Logger LOGGER = LoggerFactory.getLogger(WorkReportHelp.class);

    @Resource
    private WorkReportModel workReportModel;
    @Resource
    private WorkReportSetModel workReportSetModel;
    @Resource
    private ChartQueryHelp chartQueryHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private ChartDtoHelp chartDtoHelp;
    @Resource
    private UserModel userModel;
    @Resource
    private ThroughHelp throughHelp;
    @Resource
    private ChartFeignClient chartFeignClient;
    @Resource
    private DepartmentModel departmentModel;

    /**
     * 新建时格式化解释
     * 重构前 -> com.xbongbong.saas.service.impl.WorkReportServiceImpl#formatAddExplain(com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO)
     * @param formatExplainDTO
     * @throws XbbException
     */
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        String corpid = formatExplainDTO.getCorpid();
        String userId = formatExplainDTO.getUserId();
        Integer subBusinessType = formatExplainDTO.getSubBusinessType();
        if (subBusinessType == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(subBusinessType);
        SaasSpecialParamPojo saasSpecialParamPojo = formatExplainDTO.getSaasSpecialParamPojo();
        int workReportDate = 0;
        Boolean flag = false;
        if (saasSpecialParamPojo != null && !(Objects.equals(saasSpecialParamPojo.getReportStartDate(), null))) {
            flag = true;
        }
        Integer type = 1;
        switch (redundantTemplateTypeEnum) {
            case WORKREPORT_DAILY:
                if (flag) {
                    workReportDate = DateUtil.getInt(saasSpecialParamPojo.getReportStartDate(),new SimpleDateFormat("yyyy-MM-dd"));
                } else {
                    workReportDate = DateUtil.getTodayInt();
                }
                type = ReportTypeEnum.DAY.getCode();
                break;
            case WORKREPORT_WEEKLY:
                if (flag) {
                    workReportDate = DateUtil.getWeekMorningInSomeday(DateUtil.getInt(saasSpecialParamPojo.getReportStartDate(),new SimpleDateFormat("yyyy-MM-dd")));
                } else {
                    workReportDate = DateUtil.getThisWeekMorning();
                }
                type = ReportTypeEnum.WEEK.getCode();
                break;
            case WORKREPORT_MONTHLY:
                if (flag) {
                    workReportDate = DateUtil.getFirstDateOfMonthInSomeday(DateUtil.getInt(saasSpecialParamPojo.getReportStartDate(),new SimpleDateFormat("yyyy-MM-dd")));
                } else {
                    workReportDate = DateUtil.getFirstDateOfThisMonth();
                }
                type = ReportTypeEnum.MONTH.getCode();
                break;
            default:
                break;
        }
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, WorkReportFieldEnum.THIS_PLAN.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo;
                List<WorkPlanEntity> thisPlans = workReportModel.getThisPlansByTime(corpid, userId, type, workReportDate);
                saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                saasParticularAttributePoJo = saasParticularAttributePoJo == null ? new SaasParticularAttributePoJo() : saasParticularAttributePoJo;
                JSONArray array = new JSONArray();

                for (WorkPlanEntity entity : thisPlans) {
                    JSONObject obj = new JSONObject();
                    obj.put(WorkReportPlanEnum.ID.getAttr(), entity.getId());
                    obj.put(WorkReportPlanEnum.CONTENT.getAttr(), entity.getContent());
                    obj.put(WorkReportPlanEnum.STATUS.getAttr(), entity.getStatus());
                    array.add(obj);
                }
                saasParticularAttributePoJo.setInitialValue(array);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            } else if (Objects.equals(attr, WorkReportFieldEnum.NEXT_PLAN.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                saasParticularAttributePoJo.setInitialValue(new ArrayList<>());
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            } else if (Objects.equals(attr, WorkReportFieldEnum.TYPE.getAttr())) {
//                List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
//                ItemPoJo itemPoJo;
//                switch (redundantTemplateTypeEnum) {
//                    case WORKREPORT_DAILY:
//                        itemPoJo = itemPoJos.get(0);
//                        itemPoJo.setChecked(true);
//                        itemPoJo.setText(WorkReportTypeEnum.DAILY.getName());
//                        itemPoJo.setValue(WorkReportTypeEnum.DAILY.getType().toString());
//                        break;
//                    case WORKREPORT_WEEKLY:
//                        itemPoJo = itemPoJos.get(1);
//                        itemPoJo.setChecked(true);
//                        itemPoJo.setText(WorkReportTypeEnum.WEEKLY.getName());
//                        itemPoJo.setValue(WorkReportTypeEnum.WEEKLY.getType().toString());
//                        break;
//                    case WORKREPORT_MONTHLY:
//                        itemPoJo = itemPoJos.get(2);
//                        itemPoJo.setChecked(true);
//                        itemPoJo.setText(WorkReportTypeEnum.MONTHLY.getName());
//                        itemPoJo.setValue(WorkReportTypeEnum.MONTHLY.getType().toString());
//                        break;
//                    default:
//                        break;
//                }
            } else if (Objects.equals(attr, WorkReportFieldEnum.REPORT_DATE.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                saasParticularAttributePoJo = saasParticularAttributePoJo == null ? new SaasParticularAttributePoJo() : saasParticularAttributePoJo;
                DefaultAttrPoJo defaultAttrPoJo = fieldAttrEntity.getDefaultAttr();
                defaultAttrPoJo.setDefaultType("dateByBackEnd");
                defaultAttrPoJo.setDefaultValue(workReportDate + "");
                saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt() + TimeConstant.SECONDS_PER_DAY);
                saasParticularAttributePoJo.setLimitType(true);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            } else if (Objects.equals(attr,WorkReportFieldEnum.THIS_STATISTIC.getAttr())){
                WorkReportDetailStatisticsVO statisticsVO = getStatistic(subBusinessType,userId,corpid,workReportDate,"");
                DefaultAttrPoJo defaultAttrPoJo = fieldAttrEntity.getDefaultAttr();
                defaultAttrPoJo.setDefaultValue(JSONObject.toJSONString(statisticsVO.getWorkReportDetailStatisicPojo()));
            } else if(Objects.equals(attr,WorkReportFieldEnum.CC.getAttr())){
                UserEntity userEntity = new UserEntity();
                BeanUtil.copyProperties(formatExplainDTO.getLoginUser(),userEntity);
                DefaultAttrPoJo defaultAttrPojo = getCcUser(userEntity,type);
                fieldAttrEntity.setDefaultAttr(defaultAttrPojo);
            } else if (Objects.equals(attr,WorkReportFieldEnum.APPROVED_PEOPLE.getAttr())){
                UserEntity userEntity = new UserEntity();
                BeanUtil.copyProperties(formatExplainDTO.getLoginUser(),userEntity);
                DefaultAttrPoJo defaultAttrPojo = getApprovedPeople(userEntity,type);
                fieldAttrEntity.setDefaultAttr(defaultAttrPojo);
            }

        }
        formatExplainDTO.setExplainList(explainList);
    }

    /**
     * 详情获取工作报告统计
     * 重构前 -> com.xbongbong.saas.service.impl.WorkReportServiceImpl#getStatistic(java.lang.Integer, java.lang.String, java.lang.String, java.lang.Integer, java.lang.String)
     * @param businessType
     * @param userId
     * @param corpid
     * @param reportTime
     * @param statisticContent
     * @return
     * @throws XbbException
     */
    public WorkReportDetailStatisticsVO getStatistic(Integer businessType, String userId, String corpid, Integer reportTime, String statisticContent) throws XbbException{
        WorkReportEnum workReportEnum = WorkReportEnum.getByCode(businessType);
        Integer startTime = 0;
        Integer endTime = 0;
        if (Objects.nonNull(workReportEnum)) {
            switch (workReportEnum) {
                case WORKREPORT_DAILY:
                    startTime = DateUtil.getTodayInt(reportTime);
                    endTime = startTime + TimeConstant.SECONDS_PER_DAY;
                    break;
                case WORKREPORT_WEEKLY:
                    startTime = DateUtil.getWeekMorningInSomeday(reportTime);
                    endTime = DateUtil.getWeekLastDayInSomeday(reportTime);
                    break;
                case WORKREPORT_MONTHLY:
                    startTime = DateUtil.getFirstDateOfMonthInSomeday(reportTime);
                    endTime = DateUtil.getLastDateOfMonthInSomeday(reportTime);
                    break;
                default:
                    break;
            }
        }
        Boolean needUpdate = reportTime >= startTime && reportTime < endTime;
        WorkReportSetEntity workReportSetEntity = new WorkReportSetEntity();
        if (Objects.nonNull(workReportEnum)) {
            WorkReportTypeEnum workReportTypeEnum = WorkReportTypeEnum.getByName(workReportEnum.getName());
            if (Objects.nonNull(workReportTypeEnum)) {
                workReportSetEntity = workReportSetModel.getByType(workReportTypeEnum.getType(), corpid);
            }
        }
        JSONObject statisticOption = new JSONObject();
        if (workReportSetEntity != null) {
            statisticOption = workReportSetEntity.getStatisticOption();
        }
        statisticOption = statisticOption != null ? statisticOption : new JSONObject();
        WorkReportDetailStatisicPojo workReportDetailStatisticsPojo = new WorkReportDetailStatisicPojo();
        List<WorkReportDetailStatisticResultPojo> statisticResultList = new ArrayList<>();
        if (needUpdate){
            //需要更新统计数据
            statisticData4Update(workReportDetailStatisticsPojo, statisticResultList, statisticOption, statisticContent, corpid, userId, startTime, endTime);
        }else {
            //只展示统计数据
            statisticData4Show(workReportDetailStatisticsPojo, statisticResultList, statisticOption, statisticContent, corpid, userId, startTime, endTime);
        }
        WorkReportDetailStatisticsVO statisticsVO = new WorkReportDetailStatisticsVO();
        statisticsVO.setNeedUpdate(needUpdate);
        statisticsVO.setWorkReportDetailStatisicPojo(workReportDetailStatisticsPojo);
        statisticsVO.setStatisticResultList(statisticResultList);
        return statisticsVO;
    }

    /**
     * 更新工作报告的统计数据
     * 重构前 -> com.xbongbong.saas.service.impl.WorkReportServiceImpl#statisticData4Update(com.xbongbong.pro.webdetail.pojo.WorkReportDetailStatisicPojo, java.util.List, com.alibaba.fastjson.JSONObject, java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.Integer)
     * @param workReportDetailStatisticsPojo
     * @param statisticResultList
     * @param statisticOption
     * @param statisticContent
     * @param corpid
     * @param userId
     * @param startTime
     * @param endTime
     * @throws XbbException
     */
    private void statisticData4Update(WorkReportDetailStatisicPojo workReportDetailStatisticsPojo, List<WorkReportDetailStatisticResultPojo> statisticResultList, JSONObject statisticOption, String statisticContent, String corpid, String userId, Integer startTime, Integer endTime) throws XbbException {
        if (statisticOption == null || statisticOption.isEmpty()) {
            return;
        }
        //不一定是登录员工
        UserEntity userEntity = userModel.getByKey(userId, corpid);
        if (userEntity == null) {
            // 如果人员离职，只展示统计数据，by凤娇
            statisticData4Show(workReportDetailStatisticsPojo, statisticResultList, statisticOption, statisticContent, corpid, userId, startTime, endTime);
            return;
        }
        //工作报告统计参数pojo
        ChartResultPojo chartResultPojo = chartDtoHelp.getChartResultPojo4OneTotal(userEntity, startTime, endTime);
        NumFormatEnum numFormatEnum = NumFormatEnum.getByCode(chartResultPojo.getNumFormat());
        TimePojo timePojo = new TimePojo(TimeTypeEnum.CUSTOM.getCode(), startTime, endTime);
        //读取工作报告枚举，保证顺序
        List <StatisticOptionEnum> allEnum = StatisticOptionEnum.getAllEnum();
        StageFindStrategy stageFindStrategy = StageFindFactory.getStageFindStrategy(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
        //查出不统计的取消阶段
        Set<String> saleStageCodeIn = stageFindStrategy.findStageCodeList(corpid, new StageFindPojo(StageTypeEnum.getExceptCancelType()));
        for (StatisticOptionEnum optionEnum : allEnum ) {
            int enable = StringUtil.toInt(statisticOption.getString(optionEnum.getAttr()),0);
            if (enable != 1) {
                // 没有启用的不展示
                continue;
            }
            // 封装返回统计数据
            switch (optionEnum) {
                case CUSTOMER_ADD_COUNT:
                    //客户数量可能比较大，从统计服务获取
                    String total = getChartResultValue(chartResultPojo, SystemCodeEnum.CUSTOMER_ADD_HOME_BOARD);
                    total = Objects.isNull(total) ? "0" : total;
                    workReportDetailStatisticsPojo.setCustomerAddCount(StringUtil.toInt(total, 0));
                    workReportDetailStatisticsPojo.setCustomerAddCountVisble(BasicConstant.ONE);
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, total, SystemCodeEnum.CUSTOMER_ADD_HOME_BOARD, optionEnum);
                    break;
                case CONTRACT_ADD_COUNT:
                    BoolQueryBuilder boolQueryBuilder = chartQueryHelp.contractQuery4SignNoRed(chartResultPojo);
                    ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_CONTRACT, boolQueryBuilder, null);
                    total = Objects.isNull(elasticAggsPojo.getTotal()) ? "0" : elasticAggsPojo.getTotal();
                    workReportDetailStatisticsPojo.setContractAddCount(StringUtil.toInt(total, 0));
                    workReportDetailStatisticsPojo.setContractAddCountVisble(BasicConstant.ONE);
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, total, SystemCodeEnum.CONTRACT_COUNT_BOARD, optionEnum);
                    break;
                case CONTRACT_AMOUNT:
                    //合同金额和回款需要考虑业绩分配，直接通过feign方式调用统计端结果
                    Double amount = getChartResultValue4Double(chartResultPojo, SystemCodeEnum.CONTRACT_AMOUNT_BOARD);
                    workReportDetailStatisticsPojo.setContractAmount(amount);
                    workReportDetailStatisticsPojo.setContractAmountVisble(BasicConstant.ONE);
                    //格式化金额
                    String value = ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, amount, numFormatEnum, chartResultPojo.getNumFormatFlag());
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, String.valueOf(value), SystemCodeEnum.CONTRACT_AMOUNT_BOARD, optionEnum);
                    break;
                case COMMUNICATE_ADD_COUNT:
                    //跟进记录数量可能比较大，从统计服务获取
                    total = getChartResultValue(chartResultPojo, SystemCodeEnum.COMMUNICATE_ADD_BOARD);
                    total = Objects.isNull(total) ? "0" : total;
                    workReportDetailStatisticsPojo.setCommunicateAddCount(StringUtil.toInt(total, 0));
                    workReportDetailStatisticsPojo.setCommunicateAddCountVisble(BasicConstant.ONE);
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, total, SystemCodeEnum.COMMUNICATE_ADD_BOARD, optionEnum);
                    break;
                case OPPORTUNITY_ADD_COUNT:
                    //阶段：0其他普通类型，1赢单，2输单，3取消，不统计取消
                    //List<Integer> saleStageCodeIn = saleStageModel.statisticStageCodeIn(chartResultPojo.getCorpid(), null, SaleStageTypeEnum.getCode4Add());
                    boolQueryBuilder = chartQueryHelp.opportunityQuery4Create(chartResultPojo, "addTime", true, saleStageCodeIn, true);
                    elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_OPPORTUNITY, boolQueryBuilder, null);
                    total = Objects.isNull(elasticAggsPojo.getTotal()) ? "0" : elasticAggsPojo.getTotal();
                    workReportDetailStatisticsPojo.setOpportunityAddCount(StringUtil.toInt(total, 0));
                    workReportDetailStatisticsPojo.setOpportunityAddCountVisble(BasicConstant.ONE);
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, total, SystemCodeEnum.OPPORTUNITY_ADD_COUNT_BOARD, optionEnum);
                    break;
                case OPP_AMOUNT:
                    //阶段：0其他普通类型，1赢单，2输单，3取消，不统计取消
                    //saleStageCodeIn = saleStageModel.statisticStageCodeIn(chartResultPojo.getCorpid(), null, SaleStageTypeEnum.getCode4Add());
                    boolQueryBuilder = chartQueryHelp.opportunityQuery4Create(chartResultPojo, "addTime", true, saleStageCodeIn, true);
                    SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("aggs01").field(SalesOpportunityEnum.getEsAttr4Keyword(SalesOpportunityEnum.ESTIMATE_AMOUNT));
                    JSONObject result = esHelper.elasticAggs4NoBuckets2Object(IndexTypeEnum.IDX_SAAS_OPPORTUNITY, boolQueryBuilder, sumAggregationBuilder);
                    amount = result.getJSONObject("aggregations").getJSONObject("aggs01").getDouble("value");
                    workReportDetailStatisticsPojo.setOppAmount(amount);
                    workReportDetailStatisticsPojo.setOppAmountVisble(BasicConstant.ONE);
                    //格式化金额
                    value = ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, amount, numFormatEnum, chartResultPojo.getNumFormatFlag());
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, value, SystemCodeEnum.OPPORTUNITY_ADD_AMOUNT_BOARD, optionEnum);
                    break;
                case PAYMENT_SHEET_AMOUNT:
                    amount = getChartResultValue4Double(chartResultPojo, SystemCodeEnum.PAYMENT_ED_BOARD);
                    workReportDetailStatisticsPojo.setPaymentSheetAmount(amount);
                    workReportDetailStatisticsPojo.setPaymentSheetAmountVisble(BasicConstant.ONE);
                    value = ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, amount, numFormatEnum, chartResultPojo.getNumFormatFlag());
                    formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, String.valueOf(value), SystemCodeEnum.PAYMENT_ED_BOARD, optionEnum);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 查看工作报告（不需要更新统计数据，只做展示，即直接读取显示存库的统计数据，无需计算）
     * 重构前 -> com.xbongbong.saas.service.impl.WorkReportServiceImpl#statisticData4Show(com.xbongbong.pro.webdetail.pojo.WorkReportDetailStatisicPojo, java.util.List, com.alibaba.fastjson.JSONObject, java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.Integer)
     * @param workReportDetailStatisticsPojo
     * @param statisticResultList
     * @param statisticOption
     * @param statisticContent
     * @param corpid
     * @param userId
     * @param startTime
     * @param endTime
     */
    private void statisticData4Show(WorkReportDetailStatisicPojo workReportDetailStatisticsPojo, List<WorkReportDetailStatisticResultPojo> statisticResultList, JSONObject statisticOption, String statisticContent, String corpid, String userId, Integer startTime, Integer endTime) {
        //不一定是登录员工，只用到corpid、userId
        UserEntity userEntity = new UserEntity();
        userEntity.setCorpid(corpid);
        userEntity.setUserId(userId);
        //工作报告统计参数pojo
        ChartResultPojo chartResultPojo = chartDtoHelp.getChartResultPojo4OneTotal(userEntity, startTime, endTime);
        NumFormatEnum numFormatEnum = NumFormatEnum.getByCode(chartResultPojo.getNumFormat());
        TimePojo timePojo = new TimePojo(TimeTypeEnum.CUSTOM.getCode(), startTime, endTime);
        WorkReportDetailStatisicPojo tempPojo;
        try {
            tempPojo = JSONObject.parseObject(statisticContent, WorkReportDetailStatisicPojo.class);
            tempPojo = tempPojo == null ? new WorkReportDetailStatisicPojo() : tempPojo;
            tempPojo.statisticSetFilter(statisticOption);
            BeanUtil.copyProperties(tempPojo, workReportDetailStatisticsPojo);
            //格式化返回给前端的统计list
            if (statisticOption == null || statisticOption.isEmpty()) {
                return;
            }
            //读取工作报告枚举，保证顺序
            List <StatisticOptionEnum> allEnum = StatisticOptionEnum.getAllEnum();
            for (StatisticOptionEnum optionEnum : allEnum ) {
                int enable = StringUtil.toInt(statisticOption.getString(optionEnum.getAttr()),0);
                if (enable != 1) {
                    // 没有启用的不展示
                    continue;
                }
                // 封装返回统计数据
                switch (optionEnum) {
                    case CUSTOMER_ADD_COUNT:
                        //直接读取显示存库的统计数据，无需计算
                        Integer count = tempPojo.getCustomerAddCount();
                        String value = count == null ? "0" : String.valueOf(count);
                        workReportDetailStatisticsPojo.setCustomerAddCount(StringUtil.toInt(value, 0));
                        workReportDetailStatisticsPojo.setCustomerAddCountVisble(BasicConstant.ONE);
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, value, SystemCodeEnum.CUSTOMER_ADD_HOME_BOARD, StatisticOptionEnum.CUSTOMER_ADD_COUNT);
                        break;
                    case CONTRACT_ADD_COUNT:
                        count = tempPojo.getContractAddCount();
                        value = count == null ? "0" : String.valueOf(count);
                        workReportDetailStatisticsPojo.setContractAddCount(StringUtil.toInt(value, 0));
                        workReportDetailStatisticsPojo.setContractAddCountVisble(BasicConstant.ONE);
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, value, SystemCodeEnum.CONTRACT_COUNT_BOARD, StatisticOptionEnum.CONTRACT_ADD_COUNT);
                        break;
                    case CONTRACT_AMOUNT:
                        Double amount = tempPojo.getContractAmount();
                        amount = amount == null ? 0D : amount;
                        value = ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, amount, numFormatEnum, chartResultPojo.getNumFormatFlag());
                        workReportDetailStatisticsPojo.setContractAmount(amount);
                        workReportDetailStatisticsPojo.setContractAmountVisble(BasicConstant.ONE);
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, String.valueOf(value), SystemCodeEnum.CONTRACT_AMOUNT_BOARD, StatisticOptionEnum.CONTRACT_AMOUNT);
                        break;
                    case COMMUNICATE_ADD_COUNT:
                        count = tempPojo.getCommunicateAddCount();
                        value = count == null ? "0" : String.valueOf(count);
                        workReportDetailStatisticsPojo.setCommunicateAddCount(StringUtil.toInt(value, 0));
                        workReportDetailStatisticsPojo.setCommunicateAddCountVisble(BasicConstant.ONE);
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, value, SystemCodeEnum.COMMUNICATE_ADD_BOARD, StatisticOptionEnum.COMMUNICATE_ADD_COUNT);
                        break;
                    case OPPORTUNITY_ADD_COUNT:
                        count = tempPojo.getOpportunityAddCount();
                        value = count == null ? "0" : String.valueOf(count);
                        workReportDetailStatisticsPojo.setOpportunityAddCount(StringUtil.toInt(value, 0));
                        workReportDetailStatisticsPojo.setOpportunityAddCountVisble(BasicConstant.ONE);
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, value, SystemCodeEnum.OPPORTUNITY_ADD_COUNT_BOARD, StatisticOptionEnum.OPPORTUNITY_ADD_COUNT);
                        break;
                    case OPP_AMOUNT:
                        amount = tempPojo.getOppAmount();
                        amount = amount == null ? 0D : amount;
                        //格式化金额
                        workReportDetailStatisticsPojo.setOppAmount(amount);
                        workReportDetailStatisticsPojo.setOppAmountVisble(BasicConstant.ONE);
                        value = ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, amount, numFormatEnum, chartResultPojo.getNumFormatFlag());
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, value, SystemCodeEnum.OPPORTUNITY_ADD_AMOUNT_BOARD, StatisticOptionEnum.OPP_AMOUNT);
                        break;
                    case PAYMENT_SHEET_AMOUNT:
                        amount = tempPojo.getPaymentSheetAmount();
                        amount = amount == null ? 0D : amount;
                        //格式化金额
                        workReportDetailStatisticsPojo.setPaymentSheetAmount(amount);
                        workReportDetailStatisticsPojo.setPaymentSheetAmountVisble(BasicConstant.ONE);
                        value = ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, amount, numFormatEnum, chartResultPojo.getNumFormatFlag());
                        formatStatisticResultList(statisticResultList, chartResultPojo, timePojo, String.valueOf(value), SystemCodeEnum.PAYMENT_ED_BOARD, StatisticOptionEnum.PAYMENT_SHEET_AMOUNT);
                        break;
                    default:
                        break;
                }
            }
        } catch (Exception e) {
            LOGGER.info("WorkReportServiceImpl.statisticData4Show parseObject error...");
        }
    }

    /**
     * 封装统计数据
     * 重构前 -> com.xbongbong.saas.service.impl.WorkReportServiceImpl#formatStatisticResultList(java.util.List, com.xbongbong.pro.statistic.result.pojo.ChartResultPojo, com.xbongbong.pro.statistic.pojo.TimePojo, java.lang.String, com.xbongbong.pro.statistic.enums.SystemCodeEnum, com.xbongbong.pro.enums.StatisticOptionEnum)
     * @param statisticResultList
     * @param chartResultPojo
     * @param timePojo
     * @param total
     * @param systemCodeEnum
     * @param statisticOptionEnum
     * @return
     */
    private List<WorkReportDetailStatisticResultPojo> formatStatisticResultList(List<WorkReportDetailStatisticResultPojo> statisticResultList, ChartResultPojo chartResultPojo, TimePojo timePojo, String total, SystemCodeEnum systemCodeEnum, StatisticOptionEnum statisticOptionEnum) {
        ThroughDTO throughDto = new ThroughDTO(chartResultPojo, systemCodeEnum);
        String through = throughHelp.getThrough(throughDto, timePojo, ThroughSourcePageEnum.WORK_REPORT_DETAIL.getValue());
        WorkReportDetailStatisticResultPojo resultPojo = new WorkReportDetailStatisticResultPojo(statisticOptionEnum.getAttr(), statisticOptionEnum.getName(), total, through);
        statisticResultList.add(resultPojo);
        return statisticResultList;
    }


    /**
     * 从统计项目得到指标统计结果（区间总数值）
     * 重构前 -> com.xbongbong.saas.help.BasicHelper#getChartResultValue(com.xbongbong.pro.statistic.result.pojo.ChartResultPojo, com.xbongbong.pro.statistic.enums.SystemCodeEnum)
     * //todo feign的位置需要动吗
     * @param chartResultPojo
     * @param systemCodeEnum
     * @return
     */
    public String getChartResultValue(ChartResultPojo chartResultPojo, SystemCodeEnum systemCodeEnum) {
        chartResultPojo.setSystemCodeEnum(systemCodeEnum);
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        Object obj = chartFeignClient.value(chartResultPojo, lang);
        String valueStr = (String) ((XbbResponse) obj).getResult();
        return valueStr;
    }

    /**
     * 得到double类型的统计结果
     * 重构前 -> com.xbongbong.saas.help.BasicHelper#getChartResultValue4Double(com.xbongbong.pro.statistic.result.pojo.ChartResultPojo, com.xbongbong.pro.statistic.enums.SystemCodeEnum)
     * @param chartResultPojo
     * @param systemCodeEnum
     * @return
     */
    public Double getChartResultValue4Double(ChartResultPojo chartResultPojo, SystemCodeEnum systemCodeEnum) {
        String valueStr = getChartResultValue(chartResultPojo, systemCodeEnum);
        if (StringUtil.isEmpty(valueStr)){
            return 0D;
        } else {
            //double的需要把逗号去除
            valueStr = valueStr.replace(",", "");
        }
        return Double.valueOf(valueStr);
    }

    /**
     * 当前登录人 所属部门和默认发送人所属部门 取交集获取抄送人
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#getCcUser(com.xbongbong.sys.domain.entity.UserEntity, java.lang.Integer)
     * @param userEntity
     * @param type
     * @return
     * @throws XbbException
     */
    public DefaultAttrPoJo getCcUser(UserEntity userEntity,Integer type) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type",type);
        params.put("corpid",userEntity.getCorpid());
        params.put("del", DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetEntityList = workReportSetModel.findEntitys(params);
        if (Objects.isNull(workReportSetEntityList) || workReportSetEntityList.size() == 0){
            throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207022);
        }
        WorkReportSetEntity workReportSetEntity = workReportSetEntityList.get(0);
        List<Long> userDeps = JSONArray.parseArray(userEntity.getDepartment(),Long.class);
        JSONArray jsonArray = null;
        if(workReportSetEntity != null){
            jsonArray = workReportSetEntity.getCcUser();
        }
        JSONArray ccUserArray = new JSONArray();
        if(Objects.nonNull(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray effectiveDepsArray = Objects.isNull(jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS)) ? new JSONArray() : jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS);
                List<Long> depList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<IdNamePropertyPojo> depIdNameProperty = JSONArray.parseArray(effectiveDepsArray.toJSONString(),IdNamePropertyPojo.class);
                if (Objects.nonNull(depIdNameProperty) && depIdNameProperty.size() != 0){
                    for (IdNamePropertyPojo item : depIdNameProperty) {
                        depList.add(Long.valueOf(item.getId()));
                    }
                }
                // 抄送部门为空或全公司
                if (depList.isEmpty() || depList.contains(1L)) {
                    JSONArray userJson = jsonObject.getJSONArray(BasicConstant.USERS);
                    ccUserArray.addAll( Objects.isNull(userJson) ? new JSONArray() : userJson );
                } else {
                    depList.retainAll(userDeps);
                    if (depList.size()>=1) {
                        JSONArray userJson = jsonObject.getJSONArray(BasicConstant.USERS);
                        ccUserArray.addAll(Objects.isNull(userJson) ? new JSONArray() : userJson );
                    }
                }
            }
        }
        List<OptionalRangeEntity> defaultList = new ArrayList<>();
        DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
        defaultAttrPoJo.setDefaultType(StringConstant.CUSTOM);
        for (int i = 0; i < ccUserArray.size(); i++) {
            JSONObject ccUser = ccUserArray.getJSONObject(i);
            OptionalRangeEntity optionalRangeEntity = new OptionalRangeEntity();
            optionalRangeEntity.setProperty(OptionalRangeEnum.USER.getValue());
            optionalRangeEntity.setId(ccUser.getString(BasicConstant.ID));
            optionalRangeEntity.setName(ccUser.getString(BasicConstant.NAME));
            optionalRangeEntity.setEditable(BasicConstant.ONE);
            defaultList.add(optionalRangeEntity);
        }
        defaultAttrPoJo.setDefaultList(defaultList);
        return defaultAttrPoJo;
    }

    /**
     * 格式化explains时获取批阅人list
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#getApprovedPeople(com.xbongbong.sys.domain.entity.UserEntity, java.lang.Integer)
     * @param userEntity
     * @param type
     * @return
     * @throws XbbException
     */
    public DefaultAttrPoJo getApprovedPeople(UserEntity userEntity,Integer type) throws XbbException {
        // todo
        DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
        defaultAttrPoJo.setDefaultType(StringConstant.CUSTOM);
        List<IdNamePropertyPojo> defaultList = getApprovedPeopleList(userEntity, type);
        hasAllSupervisor(defaultList);
        if (CollectionUtils.isEmpty(defaultList)) {
            defaultAttrPoJo.setDefaultValue("所有上级主管");
        } else {
            defaultAttrPoJo.setDefaultValue(getStrWithComma(defaultList));
        }
        return defaultAttrPoJo;
    }

    /**
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#getApprovedPeopleList(com.xbongbong.sys.domain.entity.UserEntity, java.lang.Integer)
     * @param userEntity
     * @param type
     * @return
     * @throws XbbException
     */
    public List<IdNamePropertyPojo> getApprovedPeopleList(UserEntity userEntity, Integer type) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type",type);
        params.put("corpid",userEntity.getCorpid());
        params.put("del",DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetEntityList = workReportSetModel.findEntitys(params);
        if (Objects.isNull(workReportSetEntityList) || workReportSetEntityList.size() == 0){
            throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207022);
        }
        WorkReportSetEntity workReportSetEntity = workReportSetEntityList.get(0);
        List<Long> userDeps = JSONArray.parseArray(userEntity.getDepartment(),Long.class);
        JSONArray jsonArray = null;
        if(workReportSetEntity != null){
            jsonArray = workReportSetEntity.getCcUser();
        }
        JSONArray approvedPeople = new JSONArray();
        if(Objects.nonNull(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray effectiveDepsArray = Objects.isNull(jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS)) ? new JSONArray() : jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS);
                List<Long> depList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<IdNamePropertyPojo> depIdNameProperty = JSONArray.parseArray(effectiveDepsArray.toJSONString(),IdNamePropertyPojo.class);
                if (Objects.nonNull(depIdNameProperty) && depIdNameProperty.size() != 0){
                    for (IdNamePropertyPojo item : depIdNameProperty) {
                        depList.add(Long.valueOf(item.getId()));
                    }
                }
                Boolean flag = true;
                for (Long depId : userDeps) {
                    if (depList.contains(depId)) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    continue;
                }
                // 抄送部门为空或全公司
                if (depList.isEmpty() || depList.contains(1L)) {
                    JSONArray userJson = jsonObject.getJSONArray(BasicConstant.APPROVED_PEOPLE);
                    approvedPeople.addAll(Objects.isNull(userJson) ? new JSONArray() : userJson );
                } else {
                    depList.retainAll(userDeps);
                    if (depList.size()>=1) {
                        JSONArray userJson = jsonObject.getJSONArray(BasicConstant.APPROVED_PEOPLE);
                        approvedPeople.addAll(Objects.isNull(userJson) ? new JSONArray() : userJson );
                    }
                }
            }
        }
        List<IdNamePropertyPojo> defaultList = new ArrayList<>();
        for (int i = 0; i < approvedPeople.size(); i++) {
            JSONObject approvedPeopleJSONObject = approvedPeople.getJSONObject(i);
            IdNamePropertyPojo optionalRangeEntity = new IdNamePropertyPojo();
            optionalRangeEntity.setProperty(approvedPeopleJSONObject.getString(BasicConstant.PROPERTY));
            optionalRangeEntity.setId(approvedPeopleJSONObject.getString(BasicConstant.ID));
            optionalRangeEntity.setName(approvedPeopleJSONObject.getString(BasicConstant.NAME));
            defaultList.add(optionalRangeEntity);
        }
        return defaultList;
    }

    /**
     * 是否要替换成 所有直属上级主管
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#hasAllSupervisor(java.util.List)
     * @param defaultList
     * @return
     */
    private static boolean hasAllSupervisor(List<IdNamePropertyPojo> defaultList){
        boolean hasAllSupervisor = true;
        List<String> level = new ArrayList<>();
        for (int i = 0; i < defaultList.size(); i++) {
            level.add(defaultList.get(i).getName());
        }
        for (DynamicManagerLevelEnum dynamicManagerLevelEnum : DynamicManagerLevelEnum.values()){
            if (Objects.equals(dynamicManagerLevelEnum,DynamicManagerLevelEnum.ZERO_LEVEL)){
                continue;
            }
            if (!level.contains(dynamicManagerLevelEnum.getName())){
                hasAllSupervisor = false;
            }
        }
        if (hasAllSupervisor){
            Iterator iterator = defaultList.iterator();
            while (iterator.hasNext()){
                IdNamePropertyPojo idNamePropertyPojo = (IdNamePropertyPojo)iterator.next();
                if (Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.ONE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TWO_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.THREE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FOUR_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FIVE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SIX_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SEVEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.EIGHT_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.NINE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.ELEVEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TWELVE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.THIRTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FOURTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FIFTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SIXTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SEVENTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.EIGHTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.NINETEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TWENTY_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TOP_LEVEL.getName())
                ){
                    iterator.remove();
                }
            }
            IdNamePropertyPojo idNamePropertyPojo = new IdNamePropertyPojo();
            idNamePropertyPojo.setId("");
            idNamePropertyPojo.setProperty("");
            idNamePropertyPojo.setName("所有上级主管");
            defaultList.add(idNamePropertyPojo);
        }
        return hasAllSupervisor;
    }


    /**
     * 拼接逗号
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#getStrWithComma(java.util.List)
     * @param nameList
     * @return
     */
    private static String getStrWithComma(List nameList){
        if (nameList == null || nameList.size() == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (Object obj :nameList) {
            if (obj instanceof UserSimpPojo) {
                sb.append(((UserSimpPojo)obj).getName()).append(SymbolConstant.COMMA_ENGLISH);
            } else if(obj instanceof IdNamePojo){
                sb.append(((IdNamePojo)obj).getName()).append(SymbolConstant.COMMA_ENGLISH);
            }  else if(obj instanceof IdNamePropertyPojo){
                sb.append(((IdNamePropertyPojo)obj).getName()).append(SymbolConstant.COMMA_ENGLISH);
            } else {
                sb.append(SymbolConstant.COMMA_ENGLISH);
            }
        }
        String relatives = sb.deleteCharAt(sb.length() - 1).toString();
        return relatives;
    }

    /**
     * 当前用户是否有相应的新建工作报告功能
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#getVisibleRange(com.xbongbong.sys.domain.entity.UserEntity)
     * @param userEntity
     * @return
     */
    public WorkReportSetVisibleRange getVisibleRange(UserEntity userEntity) {
        WorkReportSetVisibleRange visibleRange = new WorkReportSetVisibleRange();
        // json字段排序
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", userEntity.getCorpid());
        param.put("del", DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetList = workReportSetModel.findEntitys(param);

        visibleRange.setDayEnable(true);
        visibleRange.setWeekEnable(true);
        visibleRange.setMonthEnable(true);

        for (WorkReportSetEntity workReportSet : workReportSetList) {
            if (Objects.equals(workReportSet.getEnable(), BasicConstant.NO_USE)) {
                disabledJsonWorkReportSet(visibleRange, workReportSet);
            }
            if (!checkUserWorkReportEnabled(userEntity, workReportSet)) {
                disabledJsonWorkReportSet(visibleRange, workReportSet);
            }
        }
        return visibleRange;
    }

    /**
     * 根据工作报告设置，添加日报、周报、月报的开启配置
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#disabledJsonWorkReportSet
     * @param visibleRange
     * @param workReportSet
     */
    private void disabledJsonWorkReportSet(WorkReportSetVisibleRange visibleRange, WorkReportSetEntity workReportSet) {
        WorkReportTypeEnum typeEnum = WorkReportTypeEnum.getByType(workReportSet.getType());
        if (typeEnum == null) {
            return;
        }

        switch (typeEnum) {
            default:
                break;
            case DAILY:
                visibleRange.setDayEnable(false);
                break;
            case WEEKLY:
                visibleRange.setWeekEnable(false);
                break;
            case MONTHLY:
                visibleRange.setMonthEnable(false);
                break;
        }
    }

    /**
     * 判断用户是有有操作工作报告的能力
     * 重构前 -> com.xbongbong.paas.service.impl.WorkReportSetServiceImpl#checkUserWorkReportEnabled
     * @param userEntity
     * @param workReportSet
     * @return
     */
    private boolean checkUserWorkReportEnabled(UserEntity userEntity, WorkReportSetEntity workReportSet) {
        if (Objects.equals(userModel.getDataPermission(userEntity, true), DataPermissionEnum.ALL.getCode())) {
            return true;
        }
        List<OptionalRangeEntity> list = new ArrayList<>();
        if (workReportSet != null && workReportSet.getVisibleObject() != null) {
            try {
                list = workReportSet.getVisibleObject().toJavaList(OptionalRangeEntity.class);
            } catch (JSONException e) {
                list = new ArrayList<>();
            }
        }

        if (list.size() == 0) {
            return true;
        }

        List<String> userIdList = new ArrayList<>();
        List<String> roleIdList = new ArrayList<>();
        List<String> departmentIdList = new ArrayList<>();
        for (OptionalRangeEntity rangeEntity : list) {
            String property = rangeEntity.getProperty();
            String id = rangeEntity.getId();
            if (OptionalRangeEnum.DEPT.getValue().equals(property)) {
                departmentIdList.add(id);
            } else if (OptionalRangeEnum.ROLE.getValue().equals(property)) {
                roleIdList.add(id);
            } else if (OptionalRangeEnum.USER.getValue().equals(property)) {
                userIdList.add(id);
            }
        }
        if (userIdList.size() == 0 && roleIdList.size() == 0 && departmentIdList.size() == 0) {
            // 三个权限设置都为空，默认给予用户新建工作报告的功能
            return true;
        }

        if (!userIdList.contains(userEntity.getUserId())) {
            List<String> userRoles = StringUtil.roleIdToList(userEntity.getRoleIds());
            if (userRoles == null) {
                userRoles = new ArrayList<>();
            }
            userRoles.retainAll(roleIdList);
            if (userRoles.size() == 0) {
                List<String> userDepIdList = JSON.parseArray(userEntity.getDepartment(), String.class);
                if (userDepIdList.size() == 0 || departmentIdList.size() == 0) {
                    // 数据异常，不可能存在没有部门的员工
                    // 或设置的用户不为空且用户不在设置的用户列表里，而设置角色和部门是空的（反推得出此结论）
                    return false;
                } else {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("corpid", userEntity.getCorpid());
                    params.put("idIn", userDepIdList);
                    params.put("del", 0);
                    params.put("columns", "dep_id_router");
                    List<DepartmentEntity> userDepList = departmentModel.findEntitys(params);
                    if (userDepList.size() == 0) {
                        // 数据异常，不可能存在没有部门的员工
                        return false;
                    } else {
                        List<String> packagedWorkReportSetDepIdList = new ArrayList<>();
                        String tempVirgule = "|";
                        for (String workReportDepId : departmentIdList) {
                            packagedWorkReportSetDepIdList.add(tempVirgule + workReportDepId + tempVirgule);
                        }
                        boolean isSetDepIn = false;
                        for (DepartmentEntity department : userDepList) {
                            for (String packagedWorkReportSetDepId : packagedWorkReportSetDepIdList) {
                                isSetDepIn = department.getDepIdRouter().contains(packagedWorkReportSetDepId);
                                if (isSetDepIn) {
                                    break;
                                }
                            }
                            if (isSetDepIn) {
                                break;
                            }
                        }
                        if (!isSetDepIn) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
}
